package cc.fathervideoplayer

import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.speech.tts.TextToSpeech
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.core.app.ActivityCompat
import androidx.core.text.isDigitsOnly
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

private const val KEY_LAST_PLAY_INDEX_TV = "last_play_index_tv"
private const val KEY_CACHE_TV = "video_list_tv"

class TVSeriesActivity : ComponentActivity() {

    var list = mutableListOf<File>()
    var index = -1
    val tts by lazy {
        TextToSpeech(this) {
            if (it == TextToSpeech.SUCCESS) {
                Toast.makeText(this, "语音引擎初始化成功", Toast.LENGTH_SHORT).show()
            }
        }
    }
    var isInEditMode = false
    var selectList = mutableListOf<File>()
    private val rv by lazy {
        findViewById<RecyclerView>(R.id.rv)
    }

    val lujuDirs by lazy {
        val sdcard = File("/storage/0000-0000")
        val external = Environment.getExternalStorageDirectory()
        val lujuDirs = mutableListOf<File>()
        val allFiles = mutableListOf<File>()
        sdcard.listFiles()?.let { sd ->
            allFiles.addAll(sd)
        }
        external.listFiles()?.let { ex ->
            allFiles.addAll(ex)
        }
        for (f in allFiles) {
            if (f.isDirectory && f.name.startsWith("电视剧")) {
                lujuDirs.add(f)
            }
        }
        lujuDirs
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MMKV.initialize(this)
        setContentView(R.layout.activity_main)
        findViewById<TextView>(R.id.title).text = title
        tts
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
            0
        )
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
            val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse("package:$packageName"))
            startActivity(intent)
            return
        }

        rv.layoutManager = LinearLayoutManager(this)
        index = mmkv.decodeInt(KEY_LAST_PLAY_INDEX_TV, -1)
        rv.adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
            override fun onCreateViewHolder(
                parent: ViewGroup,
                viewType: Int,
            ): RecyclerView.ViewHolder {
                return object :
                    RecyclerView.ViewHolder(
                        layoutInflater.inflate(
                            R.layout.list_item_video,
                            parent,
                            false
                        )
                    ) {}
            }

            override fun getItemCount(): Int {
                return list.size
            }

            override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
                val file = list[position]
                Glide.with(this@TVSeriesActivity).load(file)
                    .into(holder.itemView.findViewById<ImageView>(R.id.iv))
                (holder.itemView.findViewById<TextView>(R.id.tvTitle)).also {
                    it.text = file.name
                    if (isInEditMode) {
                        val contains = selectList.contains(file)
                        it.setTextColor(if (contains) Color.WHITE else Color.BLACK)
                        holder.itemView.setBackgroundColor(if (contains) Color.parseColor("#00C7CD") else Color.WHITE)
                    } else {
                        it.setTextColor(if (index == position) Color.WHITE else Color.BLACK)
                        holder.itemView.setBackgroundColor(if (index == position) Color.parseColor("#6182FF") else Color.WHITE)
                    }
                }
                holder.itemView.setOnLongClickListener {
                    isInEditMode = !isInEditMode
                    updateSelectMode()
                    true
                }
                holder.itemView.setOnClickListener {
                    if (isInEditMode) {
                        if (selectList.contains(file)) {
                            selectList.remove(file)
                        } else {
                            selectList.add(file)
                        }
                        notifyDataSetChanged()
                        return@setOnClickListener
                    }
                    if (index == position) {
                        mmkv.encode(KEY_LAST_PLAY_INDEX_TV, position)
                        file.playVideo(this@TVSeriesActivity)
                        return@setOnClickListener
                    }
                    index = position
                    var fName = file.getFileNameWithoutExt()
                    if (fName.contains('-')) {

                        fName.split('-').also {
                            if (it[1].isDigitsOnly()) {
                                val num = it[1].toInt()
                                fName = it[0] + "第" + num + "集"
                            }
                        }
                    }
                    tts.speak(
                        fName,
                        TextToSpeech.QUEUE_FLUSH,
                        null,
                        null
                    )
                    notifyDataSetChanged()
                }
            }
        }
        val cache = getCacheList(KEY_CACHE_TV)
        if (cache.isNullOrEmpty()) {
            scanTv()
        } else {
            this.list = cache
            rv.adapter?.notifyDataSetChanged()
        }

        val view: View = findViewById(R.id.reScan)
        view.setOnLongClickListener {
            AlertDialog.Builder(this).setMessage("是否重新扫描")
                .setNegativeButton("取消", null)
                .setPositiveButton("确定") { dialogInterface, i ->
                    mmkv.encode(KEY_LAST_PLAY_INDEX_TV, -1)
                    scanTv()
                }.show()
            true
        }
        if (index > 0) {
            rv.post {
                (rv.layoutManager as LinearLayoutManager).let {
                    val count =
                        it.findLastCompletelyVisibleItemPosition() - it.findFirstCompletelyVisibleItemPosition()
                    if (index > count) {
                        rv.smoothScrollToPosition(index + count - 1)
                    }
                }
            }
        }
    }

    @OptIn(DelicateCoroutinesApi::class)
    fun scanTv() {
        GlobalScope.launch {
            val list = mutableListOf<File>()
            for (lujuDir in lujuDirs) {
                val temp = scanAll(mutableListOf(lujuDir))
                temp.sortBy { it.name }
                list.addAll(temp)
            }
            this@TVSeriesActivity.list = list
            saveCache(list, KEY_CACHE_TV)
            withContext(Dispatchers.Main) {
                rv.adapter?.notifyDataSetChanged()
            }
        }
    }

    private fun updateSelectMode() {
        val v1: CheckBox = findViewById(R.id.cbSelectAll)
        v1.isVisible = true
        val v2: View = findViewById(R.id.btnDelete)
        v2.isVisible = true
        if (isInEditMode) {
            v2.setOnClickListener {
                val cb = CheckBox(this)
                cb.text = "同时删除原文件"
                AlertDialog.Builder(this@TVSeriesActivity).setMessage("是否从列表中删除？")
                    .setView(cb)
                    .setNegativeButton("取消", null)
                    .setPositiveButton(
                        "确定"
                    ) { dialogInterface, i ->
                        list.removeAll(selectList)
                        saveCache(list, KEY_CACHE_TV)
                        rv.adapter?.notifyDataSetChanged()
                        if (cb.isChecked) {
                            GlobalScope.launch {
                                for (file in selectList) {
                                    file.delete()
                                }
                                withContext(Dispatchers.Main) {
                                    Toast.makeText(
                                        this@TVSeriesActivity,
                                        "${selectList.size}个文件已删除",
                                        Toast.LENGTH_SHORT
                                    ).show()
                                }
                                selectList.clear()
                            }
                        }
                    }.show()
            }
            v1.setOnCheckedChangeListener { compoundButton, b ->
                if (b) {
                    selectList.addAll(list)
                } else {
                    selectList.clear()
                }
                rv.adapter?.notifyDataSetChanged()
            }
        } else {
            v1.isVisible = false
            v2.isVisible = false
        }
        rv.adapter?.notifyDataSetChanged()
    }

    override fun onBackPressed() {
        if (isInEditMode) {
            isInEditMode = false
            updateSelectMode()
            return
        }
        super.onBackPressed()
    }

    override fun onPause() {
        super.onPause()
        tts.stop()
    }
}